#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "unistd.h"
#include "libringqueue.h"

void read_test(struct ring_queue *mrq, uint8_t tail_flag)
{
	uint8_t *data;
	uint32_t size;
	static int i=0;
	int32_t ret = ring_queue_read(mrq, (void **)&data, &size, tail_flag);
	if (ret != RET_QUEUE_EMPTY)
	{
		printf("\t\t\tread:size:%d ,data:%s  cnt:%d\n", size, data, i++);
		free(data);
	}
}

int32_t write_test(struct ring_queue *mrq, uint8_t *str, uint32_t size, uint8_t tail_flag, uint8_t overwrite_flag,uint8_t overwrite_tail)
{
	uint8_t *data = (uint8_t *)malloc(size);
	memcpy(data,str,size);
	int32_t ret = ring_queue_write(mrq, data, size, tail_flag, overwrite_flag,overwrite_tail);
	return ret;
}

void delete_test(struct ring_queue *mrq, uint8_t tail_flag)
{
	uint8_t *data;
	int32_t ret = ring_queue_delete(mrq, (void **)&data, tail_flag);
	if (ret != RET_QUEUE_EMPTY)
	{
		free(data);
	}
}

void main_no_thread()
{

	struct ring_queue *rq_t = ring_queue_init(8);

	write_test(rq_t, "val[0]", 10, 1, 0, 0);
	write_test(rq_t, "val[1]", 10, 1, 0, 0);
	write_test(rq_t, "val[2]", 10, 1, 0, 0);
	write_test(rq_t, "val[3]", 10, 0, 1, 0);

	list_each_print(rq_t);

	delete_test(rq_t, 0);
	write_test(rq_t, "val[4]", 10, 1, 0, 0);
	list_each_print(rq_t);


	read_test(rq_t, 1);
	write_test(rq_t, "val[5]", 10, 0, 0, 0);
	read_test(rq_t, 1);
	read_test(rq_t, 1);

	list_each_print(rq_t);
	ring_queue_deinit(rq_t);
}

uint32_t productor_ms = 200;
uint32_t consumer_ms = 250;

void *thread_productor(void *arg)
{
	struct ring_queue *rq_t = (struct ring_queue *)arg;
	int32_t ret;
	uint32_t i=0;
	uint8_t str[100];
	while(1)
	{
		sprintf(str,"%d",i++);
		ret=write_test(rq_t, str, 100*1024, 1, 0, 1);
		if(ret == RET_QUEUE_FULL)
		{
			i--;
		}
		usleep(productor_ms*1000);
	}

}

void *thread_consumer(void *arg)
{
	struct ring_queue *rq_t = (struct ring_queue *)arg;
	uint32_t i=0;
	uint8_t str[100];
	while(1)
	{
		usleep(consumer_ms*1000);
		read_test(rq_t,0);
	}
}

void main()
{
	uint8_t ch;
	pthread_t tid_productor, tid_consumer;
	struct ring_queue *rq_t = ring_queue_init(20);
	pthread_create(&tid_productor, NULL, thread_productor, (void *)rq_t);
	pthread_create(&tid_consumer, NULL, thread_consumer,  (void *)rq_t);
	while(1)
	{
		ch=getchar();
		printf("productor_ms:%d consumer_ms:%d cur_node_sum:%d\n", productor_ms, consumer_ms,rq_t->cur_node_sum);
		if(ch == 'a')
			consumer_ms = consumer_ms + 10;
		else if(ch == 'd')
			consumer_ms = consumer_ms - 10;
	}
	ring_queue_deinit(rq_t);

}
